import React, { ReactElement, useState, useEffect, useRef } from "react";
import styles from "./swiper.module.css";

// interface Props {}

function Carousel({ children, selectedIndex }) {
  // 当切换的时候，改变的就是当前位置状态
  // 所以定义当前位置,可以通过传入的selectedIndex来控制最开始显示第几个轮播图,默认从1开始
  const [active, setActive] = useState(selectedIndex);
  // 创建一个参数，对轮播图的状态进行控制  1为静止，2为进行中。主要目的是避免快速切换导致的bug。
  // 所以只有在动画结束过后，也就是静止的时候才能再次切换轮播图
  const [status, setStatus] = useState(1);
  // 获取包裹容器
  const container = useRef(null);
  // 获取当前可视区容器宽度
  const SCREEN_WIDTH = window.screen.width;

  // 统一处理，当active发生变化的时候，我们需要做的就是切换轮播图到某个位置,转场通过控制包裹容器的transform来进行切换，对transform的控制封装成setTransition函数
  useEffect(() => {
    setTransition();
  }, [active]);

  const setTransition = (offset = 0) => {
    function transitionend() {
      // 动画结束后就关闭动画
      container.current.style.transitionProperty = "none";
      // 恢复状态为1静止
      setStatus(1);
      // 当前位置在补位的位置时马上切换到本该在的位置
      if (active === 0) {
        // 使用setTimeout包裹，避免transitionProperty动画未关闭就切换的闪频
        setTimeout(() => {
          setActive(children.length);
        }, 0);
      }
      if (active === children.length + 1) {
        setTimeout(() => {
          setActive(1);
        }, 0);
      }
      container.current.removeEventListener(
        "transitionend",
        transitionend,
        false
      );
    }
    container.current.addEventListener("transitionend", transitionend, false);
    // 计算需要移动的距离并进行修改，这是切换的核心
    const distance = (1 - active) * SCREEN_WIDTH;
    container.current.style.transform = `translate3d(${
      distance + offset
    }px,0,0)`;
  };

  const handleChangeActive = (number) => {
    // 当在动画进行时，不允许切换
    if (status === 2) return;
    // 切换前先把动画参数打开
    container.current.style.transitionProperty = "all";
    // 修改状态为进行时
    setStatus(2);
    // 改变当前位置
    setActive(number);
  };

  // 为了演示是否成功，添加两个按钮来切换
  // 上一页
  const handlePrev = () => {
    // 对临界值进行处理
    handleChangeActive(active === 0 ? children.length : active - 1);
  };

  // 下一页
  const handleNext = () => {
    // 对临界值进行处理
    handleChangeActive(active === children.length + 1 ? 1 : active + 1);
  };

  return (
    <div className={styles.carousel}>
      <div ref={container} className={styles.container}>
        {React.Children.map(children, (child, index) => {
          return (
            <div
              style={{ left: index * SCREEN_WIDTH }}
              className={styles.items}
            >
              {child}
            </div>
          );
        })}
      </div>
      <div>
        <div onClick={handlePrev} className={styles.buttonLeft}>
          Left
        </div>
        <div onClick={handleNext} className={styles.buttonRight}>
          Right
        </div>
      </div>
    </div>
  );
}

export default Carousel;
